package com.it.you.base.lambda;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

public class LambdaTest2 {

    public static void main(String[] args) {
        List<Vehicle> vehicles = new ArrayList<>();
        List<String> imeis = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            List<String> singleVehicleDevices = new ArrayList<>();
            for (int j = 0; j < 1; j++) {
                String imei = RandomStringUtils.randomAlphanumeric(15);
                singleVehicleDevices.add(imei);
            }
            imeis.add(StringUtils.join(singleVehicleDevices, ','));
        }
        vehicles.add(new Vehicle("KPTSOA1K67P081452", "17620411498", "9420", 1, 4.5, imeis.get(0)));
        vehicles.add(new Vehicle("KPTCOB1K18P057071", "15073030945", "张玲", 2, 1.4, imeis.get(1)));
        vehicles.add(new Vehicle("KPTS0A1K87P080237", "19645871598", "sanri1993", 1, 3.0, imeis.get(2)));
        vehicles.add(new Vehicle("KNAJC526975740490", "15879146974", "李种", 1, 3.9, imeis.get(3)));
        vehicles.add(new Vehicle("KNAJC521395884849", "13520184976", "袁绍", 2, 4.9, imeis.get(4)));

        System.out.println(vehicles);

        // 去掉评分为 3 分以下的车
        List<Vehicle> lt3List = vehicles.stream().filter(vehicle -> vehicle.getScore() >= 3).collect(Collectors.toList());
        System.out.println("3分以下的车：" + lt3List);
        System.out.println("-------------------------------------------------");

        // 取出所有的车架号列表
        List<String> vins = vehicles.stream().map(Vehicle::getVin).collect(Collectors.toList());
        System.out.println("车架号列表：" + vins);
        System.out.println("-------------------------------------------------");

        // 按照公司 Id 进行分组
        Map<Integer, List<Vehicle>> companyIdVehicles = vehicles.stream().collect(Collectors.groupingBy(Vehicle::getCompanyId));
        System.out.println("照公司Id进行分组：" + companyIdVehicles);
        System.out.println("-------------------------------------------------");

        // 按照公司分组求司机打分和
        Map<Integer, Double> companyScore = vehicles.stream().collect(Collectors.groupingBy(Vehicle::getCompanyId, Collectors.summingDouble(Vehicle::getScore)));
        System.out.println("按照公司分组求司机打分和：" + companyScore);
        System.out.println("-------------------------------------------------");

        // 单列排序
        vehicles.sort((v1, v2) -> v2.getScore().compareTo(v1.getScore()));
        System.out.println("单列排序：" + vehicles);
        System.out.println("-------------------------------------------------");

        // 或使用 Comparator 类来构建比较器，流处理不会改变原列表，需要接收返回值才能得到预期结果
        List<Vehicle> sortByScore = vehicles.stream().sorted(Comparator.comparing(Vehicle::getScore).reversed()).collect(Collectors.toList());
        System.out.println("按照车分排序：" + companyScore);
        System.out.println("-------------------------------------------------");

        // 多列排序，score 降序，companyId 升序排列
        List<Vehicle> sortByScoreAndCompanyId = vehicles.stream().sorted(Comparator.comparing(Vehicle::getScore).reversed()
                        .thenComparing(Comparator.comparing(Vehicle::getCompanyId)))
                .collect(Collectors.toList());
        System.out.println("score降序，companyId升序排列：" + sortByScoreAndCompanyId);
        System.out.println("-------------------------------------------------");

        // 将 List 转成 Map ; key(vin) == > Vehicle
        Map<String, Vehicle> vinVehicles = vehicles.stream().collect(Collectors.toMap(Vehicle::getVin, vehicle -> vehicle));

        // 查出所有车绑定的所有设备
        //flatMap 很适合 List<List> 或 List<object []> 这种结构，可以当成一个列表来处理；像上面的设备列表，在数据库中存储的结构就是以逗号分隔的数据，而车辆列表又是一个列表数据。
        List<String> collect = vehicles.stream().map(vehicle -> {
            String deviceNos = vehicle.getDeviceNos();
            return StringUtils.split(deviceNos, ',');
        }).flatMap(Arrays::stream).collect(Collectors.toList());

        Map<Integer, List<Vehicle>> groupByCompanyId = vehicles.stream().collect(Collectors.groupingBy(Vehicle::getCompanyId));
        List<Vehicle> list = groupByCompanyId.values().stream().flatMap(List::stream).collect(Collectors.toList());
        System.out.println(list);
        System.out.println("-------------------------------------------------");

        // mapReduce 数据处理 对所有司机的总分求和
        Double reduce = vehicles.stream().parallel().map(Vehicle::getScore).reduce(0d, Double::sum);


        // 求百分比 总的分值
        Double totalScore = vehicles.stream().parallel().map(Vehicle::getScore).reduce(0d, Double::sum);
        // 查看每一个司机占的分值比重
        List<String> scores = vehicles.stream()
                .mapToDouble(vehicle -> vehicle.getScore() / totalScore)
                .mapToLong(weight -> (long) (weight * 100))
                .mapToObj(percentage -> percentage + "%")
                .collect(Collectors.toList());
        System.out.println("总分：" + totalScore + "每一个司机占的分值比重：" + scores);
        System.out.println("-------------------------------------------------");

        //anyMatch 只要有元素匹配，即返回真
        //allMatch 要求所有的元素都匹配
        //noneMatch 要求没有一个元素匹配

        // 检查是否有姓李的司机 true
        boolean anyMatch = vehicles.stream().anyMatch(vehicle -> vehicle.getName().startsWith("李"));

        // 检查是否所有司机的评分都大于 3 分 false
        boolean allMatch = vehicles.stream().allMatch(vehicle -> vehicle.getScore() > 3);

        // 检查是否有 3 公司的特务 true
        boolean noneMatch = vehicles.stream().noneMatch(vehicle -> vehicle.getCompanyId() == 3);
    }


}
